HAL SPDIFRX initialization and configuration functions migration

The goal of this page is to show how to migrate the Init sequence using STM32CubeMX2:

  • Open STM32CubeMX2 SPDIFRX configuration panel

  • Configure the SPDIFRX main features

  • Configure the advanced SPDIFRX features.

  • Configure the SPDIFRX GPIO pins.

  • Configure the SPDIFRX DMA(s) if the application requires to use the SPDIFRX in DMA mode.

  • Configure the NVIC if the application requires the SPDIFRX to be used in IT mode.

  • Generate the code.

HAL SPDIFRX configuration panel

Create a new project with the STM32CubeMX2, then start the initialization and the main configuration.

Project configuration panel

HAL SPDIFRX main features configuration

Configure the SPDIFRX main features.

SPDIFRX main feature configuration

HAL SPDIFRX advanced features configuration

Configure the advanced SPDIFRX features.

SPDIFRX advanced feature configuration

GPIO configuration

Configure the SPDIFRX1_IN0, SPDIFRX1_IN1, SPDIFRX1_IN2 and SPDIFRX1_IN3 pins.

SPDIFRX GPIO configuration

DMA configuration

Configure the DMA for SPDIFRX data and control receptions as needed.

SPDIFRX DMA configuration

NVIC configuration

Configure the NVIC in case of an interrupt.

SPDIFRX NVIC configuration

Generated HAL SPDIFRX initialization and de-initialization sequences

The SPDIFRX initialization sequence is generated in the mx_spdifrx1_init function in the mx_spdifrx1.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

Note

As the hardware may vary, this will naturally have an impact on the RCC clock, pin and NVIC interrupt line used by the application.

STM32CubeMX2 Generated : SPDIFRX initialization and de-initialization sequences

Topic

HAL1 code snippet

HAL2 code snippet

Handle declaration

SPDIFRX_HandleTypeDef hspdif1;
DMA_NodeTypeDef Node_GPDMA1_Channel1;
DMA_QListTypeDef List_GPDMA1_Channel1;
DMA_HandleTypeDef handle_GPDMA1_Channel1;
DMA_NodeTypeDef Node_GPDMA1_Channel0;
DMA_QListTypeDef List_GPDMA1_Channel0;
DMA_HandleTypeDef handle_GPDMA1_Channel0;
hal_spdifrx_config_t spdifrx_config;
hal_spdifrx_masks_t  spdifrx_mask;
hal_dma_node_t DMA_Node_SPDIFRX1_DT;
hal_dma_node_t DMA_Node_SPDIFRX1_CS;
hal_dma_handle_t hGPDMA1_CH0;
hal_dma_handle_t hGPDMA1_CH1;

Initialization and configuration sequence

static void MX_SPDIFRX1_Init(void)
{

  hspdif1.Instance = SPDIFRX;
  hspdif1.Init.InputSelection = SPDIFRX_INPUT_IN0;
  hspdif1.Init.DataFormat = SPDIFRX_DATAFORMAT_LSB;
  hspdif1.Init.Retries = SPDIFRX_MAXRETRIES_3;
  hspdif1.Init.ChannelSelection = SPDIFRX_CHANNEL_A;
  hspdif1.Init.StereoMode = SPDIFRX_STEREOMODE_ENABLE;
  hspdif1.Init.WaitForActivity = SPDIFRX_WAITFORACTIVITY_ON;
  hspdif1.Init.PreambleTypeMask = SPDIFRX_PREAMBLETYPEMASK_ON;
  hspdif1.Init.ChannelStatusMask = SPDIFRX_CHANNELSTATUS_ON;
  hspdif1.Init.ValidityBitMask = SPDIFRX_VALIDITYMASK_ON;
  hspdif1.Init.ParityErrorMask = SPDIFRX_PARITYERRORMASK_ON;
  hspdif1.Init.SymbolClockGen = ENABLE;
  hspdif1.Init.BackupSymbolClockGen = ENABLE;
  if (HAL_SPDIFRX_Init(&hspdif1) != HAL_OK)
  {
    Error_Handler();
  }

}


void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef* hspdifrx)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  if(hspdifrx->Instance==SPDIFRX)
  {

  /** Initializes the peripherals clock
  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPDIFRX;
    PeriphClkInitStruct.SpdifrxClockSelection = RCC_SPDIFRXCLKSOURCE_PLL;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler();
    }

    /* Peripheral clock enable */
    __HAL_RCC_SPDIFRX_CLK_ENABLE();
























    __HAL_RCC_GPIOD_CLK_ENABLE();
    /** SPDIFRX1 GPIO Configuration
     PD7     ------> SPDIFRX1_IN0
    */

    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF9_SPDIF;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    /* SPDIFRX DMA Init */
    /* SPDIF_RX_DT Init */
    NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
    NodeConfig.Init.Request = GPDMA1_REQUEST_SPDIF_RX_DT;
    NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
    NodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
    NodeConfig.Init.SrcInc = DMA_SINC_FIXED;
    NodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;
    NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
    NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
    NodeConfig.Init.SrcBurstLength = 1;
    NodeConfig.Init.DestBurstLength = 1;
    NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0;
    NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    NodeConfig.Init.Mode = DMA_NORMAL;
    NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
    NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
    NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
    HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel1)

    HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel1,
                              NULL, &Node_GPDMA1_Channel1)

    HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel1)

    handle_GPDMA1_Channel1.Instance = GPDMA1_Channel1;
    handle_GPDMA1_Channel1.InitLinkedList.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
    handle_GPDMA1_Channel1.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
    handle_GPDMA1_Channel1.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT0;
    handle_GPDMA1_Channel1.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    handle_GPDMA1_Channel1.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
    HAL_DMAEx_List_Init(&handle_GPDMA1_Channel1)

    HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel1, &List_GPDMA1_Channel1)

    __HAL_LINKDMA(hspdifrx, hdmaDrRx, handle_GPDMA1_Channel1);

















    /* SPDIF_RX_CS Init */
    NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
    NodeConfig.Init.Request = GPDMA1_REQUEST_SPDIF_RX_CS;
    NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
    NodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
    NodeConfig.Init.SrcInc = DMA_SINC_FIXED;
    NodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;
    NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
    NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
    NodeConfig.Init.SrcBurstLength = 1;
    NodeConfig.Init.DestBurstLength = 1;
    NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0;
    NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    NodeConfig.Init.Mode = DMA_NORMAL;
    NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
    NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
    NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
    HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel0)

    HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel0, NULL, &Node_GPDMA1_Channel0)

    HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel0)

    handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
    handle_GPDMA1_Channel0.InitLinkedList.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
    handle_GPDMA1_Channel0.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
    handle_GPDMA1_Channel0.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT0;
    handle_GPDMA1_Channel0.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    handle_GPDMA1_Channel0.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
    HAL_DMAEx_List_Init(&handle_GPDMA1_Channel0)

    HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &List_GPDMA1_Channel0)

    __HAL_LINKDMA(hSPDIFRX1, hdmaCsRx, handle_GPDMA1_Channel0);

    /* SPDIFRX interrupt Init */
    HAL_NVIC_SetPriority(SPDIF_RX_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(SPDIF_RX_IRQn);

  }

}

static void MX_GPIO_Init(void)
{
  /* GPIO Port Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
}
hal_spdifrx_handle_t *mx_spdifrx1_init(void)
{

  if(HAL_SPDIFRX_Init(&hSPDIFRX1, HAL_SPDIFRX1) != HAL_OK)
  {
    return NULL;
  }

  HAL_RCC_SPDIFRX1_EnableClock();

  if (HAL_RCC_SPDIFRX1_SetKernelClkSource(HAL_RCC_SPDIFRX1_CLK_SRC_MCG48) != HAL_OK)
  {
    return NULL;
  }

  spdifrx_config.input_selection = HAL_SPDIFRX_INPUT_0;
  spdifrx_config.data_format     = HAL_SPDIFRX_DATA_FORMAT_LSB;
  if (HAL_SPDIFRX_SetConfig(&hSPDIFRX1,&spdifrx_config) != HAL_OK)
  {
    return NULL;
  }

  if(HAL_SPDIFRX_SetSynchroRetries(&hSPDIFRX1,HAL_SPDIFRX_SYNCHRO_RETRIES_3) != HAL_OK)
  {
    return NULL;
  }

  if(HAL_SPDIFRX_SetControlChannel(&hSPDIFRX1,HAL_SPDIFRX_CONTROL_CHANNEL_A) != HAL_OK)
  {
    return NULL;
  }

  if(HAL_SPDIFRX_EnableAlignmentForStereoOverrun(&hSPDIFRX1) != HAL_OK)
  {
    return NULL;
  }

  if(HAL_SPDIFRX_EnableWaitForActivity(&hSPDIFRX1) != HAL_OK)
  {
    return NULL;
  }

  spdifrx_mask.preamble_mask     = HAL_SPDIFRX_PREAMBLE_MASK_ENABLE;
  spdifrx_mask.channel_user_mask = HAL_SPDIFRX_CHANNEL_USER_MASK_ENABLE;
  spdifrx_mask.validity_mask     = HAL_SPDIFRX_VALIDITY_MASK_ENABLE;
  spdifrx_mask.parity_error_mask = HAL_SPDIFRX_PARITY_ERROR_MASK_ENABLE;
  if(HAL_SPDIFRX_SetMasks(&hSPDIFRX1,&spdifrx_mask) != HAL_OK)
  {
    return NULL;
  }

  if(HAL_SPDIFRX_EnableSymbolClock(&hSPDIFRX1,
                                   HAL_SPDIFRX_BACKUP_SYMBOL_CLK_ENABLED) != HAL_OK)
  {
    return NULL;
  }

  HAL_RCC_GPIOD_EnableClock();

    hal_gpio_config_t  gpio_config;

  /**
    SPDIFRX1 GPIO Configuration
     PD7     ------>   SPDIFRX1_IN0
  */

  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_9;
  HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_7, &gpio_config);

  /* Enable the Event interruption for SPDIFRX */

  HAL_CORTEX_NVIC_SetPriority(SPDIFRX1_IRQn,
                              HAL_CORTEX_NVIC_PREEMP_PRIORITY_0,
                              HAL_CORTEX_NVIC_SUB_PRIORITY_0);

  HAL_CORTEX_NVIC_EnableIRQ(SPDIFRX1_IRQn);
  HAL_RCC_GPDMA1_EnableClock();

  if (HAL_DMA_Init(&hGPDMA1_CH1, HAL_GPDMA1_CH1) != HAL_OK)
  {
    return NULL;
  }

  hal_dma_direct_xfer_config_t xfer_cfg_spdifrx1_dt_dma;
  xfer_cfg_spdifrx1_dt_dma.request         = HAL_GPDMA1_REQUEST_SPDIFRX1_DT;
  xfer_cfg_spdifrx1_dt_dma.direction       = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
  xfer_cfg_spdifrx1_dt_dma.src_inc         = HAL_DMA_SRC_ADDR_FIXED;
  xfer_cfg_spdifrx1_dt_dma.dest_inc        = HAL_DMA_DEST_ADDR_INCREMENTED;
  xfer_cfg_spdifrx1_dt_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_WORD;
  xfer_cfg_spdifrx1_dt_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
  xfer_cfg_spdifrx1_dt_dma.priority        = HAL_DMA_PRIORITY_HIGH;

  if (HAL_DMA_SetConfigPeriphLinkedListCircularXfer(&hGPDMA1_CH1,
                                                    &DMA_Node_SPDIFRX1_DT,
                                                    &xfer_cfg_spdifrx1_dt_dma) != HAL_OK)
  {
    return NULL;
  }

  if (HAL_DMA_SetLinkedListXferFetchNodePort(&hGPDMA1_CH1, HAL_DMA_PORT0) != HAL_OK)
  {
    return NULL;
  }

  /* Enable the interruption for GPDMA1_CH0 */
  HAL_CORTEX_NVIC_SetPriority(GPDMA1_CH1_IRQn,
                              HAL_CORTEX_NVIC_PREEMP_PRIORITY_0,
                              HAL_CORTEX_NVIC_SUB_PRIORITY_0);

  HAL_CORTEX_NVIC_EnableIRQ(GPDMA1_CH1_IRQn);

  /* Link the Receive DMA handle to the SPDIFRX handle */
  if (HAL_SPDIFRX_SetDataDMA(&hSPDIFRX1, &hGPDMA1_CH1) != HAL_OK)
  {
    return NULL;
  }

  HAL_RCC_GPDMA1_EnableClock();

  if (HAL_DMA_Init(&hGPDMA1_CH0, HAL_GPDMA1_CH0) != HAL_OK)
  {
    return NULL;
  }

  hal_dma_direct_xfer_config_t xfer_cfg_spdifrx1_cs_dma;
  xfer_cfg_spdifrx1_cs_dma.request         = HAL_GPDMA1_REQUEST_SPDIFRX1_CS;
  xfer_cfg_spdifrx1_cs_dma.direction       = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
  xfer_cfg_spdifrx1_cs_dma.src_inc         = HAL_DMA_SRC_ADDR_FIXED;
  xfer_cfg_spdifrx1_cs_dma.dest_inc        = HAL_DMA_DEST_ADDR_INCREMENTED;
  xfer_cfg_spdifrx1_cs_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_WORD;
  xfer_cfg_spdifrx1_cs_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
  xfer_cfg_spdifrx1_cs_dma.priority        = HAL_DMA_PRIORITY_HIGH;

  if (HAL_DMA_SetConfigPeriphLinkedListCircularXfer(&hGPDMA1_CH0,
                                                    &DMA_Node_SPDIFRX1_CS,
                                                    &xfer_cfg_spdifrx1_cs_dma) != HAL_OK)
  {
    return NULL;
  }

  if (HAL_DMA_SetLinkedListXferFetchNodePort(&hGPDMA1_CH0, HAL_DMA_PORT0) != HAL_OK)
  {
    return NULL;
  }

  /* Enable the interruption for GPDMA1_CH0 */
  HAL_CORTEX_NVIC_SetPriority(GPDMA1_CH0_IRQn,
                              HAL_CORTEX_NVIC_PREEMP_PRIORITY_0,
                              HAL_CORTEX_NVIC_SUB_PRIORITY_0);

  HAL_CORTEX_NVIC_EnableIRQ(GPDMA1_CH0_IRQn);

  /* Link the Receive DMA handle to the SPDIFRX handle */
  if (HAL_SPDIFRX_SetControlDMA(&hSPDIFRX1, &hGPDMA1_CH0) != HAL_OK)
  {
    return NULL;
  }

  return &hSPDIFRX1;
}

hal_spdifrx_handle_t *mx_spdifrx1_gethandle(void)
{
  return &hSPDIFRX1;
}

Deinitialization sequence

void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef* hspdifrx)
{
  if(hspdifrx->Instance==SPDIFRX)
  {


    __HAL_RCC_SPDIFRX_CLK_DISABLE();

    HAL_GPIO_DeInit(GPIOD, GPIO_PIN_7);

    HAL_DMA_DeInit(hspdifrx->hdmaCsRx);

    HAL_DMA_DeInit(hspdifrx->hdmaDrRx);

    HAL_NVIC_DisableIRQ(SPDIF_RX_IRQn);

  }

}
void mx_spdifrx1_deinit(void)
{

  HAL_CORTEX_NVIC_DisableIRQ(SPDIFRX1_IRQn);

  (void)HAL_SPDIFRX_DeInit(&hSPDIFRX1);

  HAL_RCC_SPDIFRX1_DisableClock();

  HAL_RCC_SPDIFRX1_Reset();

  HAL_GPIO_DeInit(HAL_GPIOD, HAL_GPIO_PIN_7);

  HAL_DMA_DeInit(&hGPDMA1_CH1);

  HAL_CORTEX_NVIC_DisableIRQ(GPDMA1_CH1_IRQn);

  HAL_DMA_DeInit(&hGPDMA1_CH0);

  HAL_CORTEX_NVIC_DisableIRQ(GPDMA1_CH0_IRQn);
}